[toc]
第五章 一等函数
函数是一等对象,一等对象需满足
- 在运行时创建
- 能赋值给对象或者数据结构中的元素
- 能作为参数传递给函数
- 能作为函数的返回结果
在Python中,整数、字符串、字典等都是一等对象,函数也是一等对象,只是把函数视作一等对象的时候,简称为一等函数。
把函数视作对象
函数也是对象,本身是function
类的实例
高阶函数
接受函数作为参数,或者把函数作为返回结果的函数叫做高阶函数。常见的高阶函数有map
,filter
,sorted
等,其中map
和filter
返回的是生成器。
all
和any
的用法:
- all(iterable),如果iterable的每个元素都是真值则返回True,all([])返回True
- any(iterable),只要iterable有元素为真则返回true,all([])返回False
可调用对象
能使用()
的都被叫做可调用对象,可使用callable()
判断一个对象是否是可调用对象,python中有7中可调用对象:
- 用户定义的函数
- 内置函数
- 内置方法
- 方法
- 类,调用时会运行
__new__
方法创建一个实例,然后运行__init__
方法初始化实例,最后把实例返回给调用方。 - 类的实例,前提是类定义了
__call__
方法。 - 生成器函数,在函数中使用了
yieled
语句的
用户定义的可调用类型
只需实现__call__
方法。
例子,从打乱的列表中取出一个元素1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import random
calss BingoCage:
def __init__(self,items):
self._items = list(items)
random.shuffle(self._items)
def pick(self):
try:
return self._items.pop()
except IndexError:
raise LookupError('pick from empty BingCage')
def __call__(self):
return self.pick()
1 | 6)) bingo = BingoCage(range( |
函数内省
Wikipedia内省)的定义:
内省是指计算机程序在运行时(Run time)检查对象(Object)类型的一种能力,通常也可以称作运行时类型检查。
通俗来讲就是Python在运行时能够知道这个对象是什么,它能做什么,它包含哪些内容。
一些内省函数:
dir(object)
:它返回一个列表,这个列表中包含object的所有属性type
:返回一个对象的类型id
:返回一个对象的id
获取关于参数的信息
函数对象有个__defaults__
属性,它的值是一个元组,里面保存着定位参数和关键字参数的默认值。__kwdefaults__
包含仅限关键字参数的默认值。参数的名称在__code__
属性中,它的值是一个code对象引用。
函数注解
函数声明中的各个参数可以在:之后增加注解表达式。如果参数有默认值放在参数名和=之间。如果想添加返回值注解,在)和函数声明末尾:之间添加->和一个表达式。
注解存储在__annotations__
属性中
支持函数式编程的包
operator
itmegetter
和attrgetter
会自行构建函数,所起的作用类似于使用lambda表达式从序列中取出元素或者读取对象的属性。
itemgetter
下例利用itemgetter
排序一个数组,itemgetter()
的作用与lambda fields: fields[1]
相同,创建一个接收集合的函数,返回索引位1的元素。
1 | 'Tokyo', 'JP', 36.933, (35.689722, 139.691667)),('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),] metro_data = [( |
attrgetter
它创建的函数根据名称提取对象的属性,如果把多个属性名传给attrgetter
,它也会返回提取的值构成的元组。
例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from collections import namedtuple
'LatLong', 'lat long') LatLong = namedtuple(
'Metropolis', 'name cc pop coord') Metropolis = namedtuple(
for name,cc,pop,(lat,long) in metro_data] metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long))
0] metro_areas[
Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722, long=139.691667))
0].coord.lat metro_areas[
35.689722
from operator import attrgetter
'name','coord.lat') name_lat = attrgetter(
for city in sorted(metro_areas,key=attrgetter('coord.lat')):
print(name_lat(city))
...
('Sao Paulo', -23.547778)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
methodcaller
methodcaller
创建的函数会在对象上调用参数指定的方法。
例子1
2
3
4
5
6from operator import methodcaller
'good good study, day day up' s =
'upper') upcase = methodcaller(
upcase(s)
'GOOD GOOD STUDY, DAY DAY UP'
>>>
使用functools.partial
冻结参数
functools.partial
这个高阶函数用于部分应用一个函数。部分应用指的是,基于一个函数创建一个新的可调用对象,把原函数的某些参数固定。
例子1
2
3
4
5from operator import mul
from functools import partial
3) triple = partial(mul,
for i in range(6)] [triple(i)
[0, 3, 6, 9, 12, 15]